#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H


#include <regex.h>
#include <string>
#include <unordered_set>
#include <unordered_map>

#include "../database_pool/mysql_conn_pool.h"
#include "../log/logger.h"

class HttpRequest {
public:
    enum LINE_STATUS {
        LINE_OK = 0,
        LINE_BAD,
        LINE_OPEN
    };

   enum PARSE_STATE {
        PARSE_REQUEST_LINE = 0,
        PARSE_HEADER,
        PARSE_BODY,
        PARSE_FINISHED
    };

    enum HTTP_CODE {
        NO_REQUEST = 0,
        GET_REQUEST,
        BAD_REQUEST,
        NO_RESOURCE,
        FORBIDDEN_REQUEST,
        FILE_REQUEST,
        INTERNAL_ERROR,
        CLOSED_CONNECTION
    };

public:
    explicit HttpRequest();
    ~HttpRequest();

    void init_read_buffer(uint64_t read_buf_size);
    void reset();

    HTTP_CODE process_request();
    std::string get_path() {return m_path;}
    bool is_keepalive() const;

public:
    char *m_read_buffer{};
    uint64_t m_read_buf_size{};
    uint64_t m_read_idx{};
    uint64_t m_checked_idx{};
    uint64_t m_line_idx{};

private:
    LINE_STATUS parse_line();
    HTTP_CODE parse_request_line(const char *line);
    HTTP_CODE parse_headers(const char *line);
    HTTP_CODE parse_post_body(const char *line);
    void process_path();
    void process_body_url();

    static bool user_info_verify(const std::string &u_name, const std::string &u_passwd, bool is_login);

private:
    PARSE_STATE m_parse_state;
    std::string m_method;
    std::string m_url;
    std::string m_path;
    std::string m_version;
    std::string m_body;
    std::unordered_map<std::string, std::string> m_header_tags;
    std::unordered_map<std::string, std::string> m_body_kvs;
    static const std::unordered_set<std::string> DEFAULT_PAGES;

};


#endif //HTTP_REQUEST_H
